﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Company.Database;
using Company.Plc;
using Company.Shell.Interfaces;
using Company.Shell.Models;
using LiveCharts.Defaults;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.Windows.Media.Animation;


namespace Company.Shell.Services
{
    public class RoomManager : ObservableObject,IRoomManager
    {
        public ICommand? SelectProgramCommand { get; }
        public ICommand? RunCommand { get; }
        public ICommand? StopCommand { get; }
        private IPlc Plc { get;  }
        private IConfigProvider ConfigProvider { get; }
        private ICacheManager CacheManager { get; }
        private IAlarmRepository AlarmRepository { get; }
        private ProgramManager ProgramManager { get; } = null!;

        public RoomManager(
            IAlarmRepository alarmRepository,
            ProgramManager programManager,
            ICacheManager cacheManager,
            IConfigProvider configProvider, 
            IPlc plc)
        {
            AlarmRepository = alarmRepository;
            ProgramManager = programManager;
            CacheManager = cacheManager;
            Plc = plc;
            ConfigProvider = configProvider;
            SelectProgramCommand = new RelayCommand<ProgramEntity>(OnSelectProgramCommand);
            RunCommand = new  AsyncRelayCommand(OnRunCommand);
            StopCommand = new AsyncRelayCommand(OnStopCommand);
        }
         /// <summary>
         /// 结束运行房间
         /// </summary>
        private async Task  OnStopCommand()
        {
            if (CurrentRoom != null)
            {
                await CurrentRoom.StopAsync();
            }
        }
        /// <summary>
        /// 开始运行房间
        /// </summary>
        private async Task OnRunCommand()
        {
            if(CurrentRoom != null)
            {
                await CurrentRoom.RunAsync();
            }
        }

        //为当前房间选定要运行的程序
        private void OnSelectProgramCommand(ProgramEntity? program)
        {
            if(CurrentRoom != null || program != null) 
            {
                CurrentRoom.Program = program;

                //计算时间
                var temperatures = CurrentRoom.Program.Temperature as IList<ObservablePoint>;
                var humidities = CurrentRoom.Program.Humidities as IList<ObservablePoint>;
                ObservablePoint? temperature = temperatures.LastOrDefault();
                ObservablePoint? humidity = humidities.LastOrDefault();
                if (temperature != null && humidity != null)
                {
                    var minute = temperature.X > humidity.X ? temperature.X : humidity.X;//取最大时间
                    var timespan = TimeSpan.FromMinutes(minute);
                    CurrentRoom.TotalTime = timespan;
                }
            }
        }

        private ObservableCollection<RoomEntity> rooms = [];
        public ObservableCollection<RoomEntity> Rooms
        {
            get => rooms;
            set => SetProperty(ref rooms, value);
        }

        private RoomEntity? currentRoom;

        public RoomEntity? CurrentRoom
        {
            get => currentRoom;
            set => SetProperty(ref currentRoom, value);
        }
        private readonly object _lock = new();//互斥锁，防止多线程同时初始化

        public async Task Initialize()
        {
            ObservableCollection<RoomEntity> collection = [];
            await Task.Delay(500);
            int count = ConfigProvider.Config.SoftwareConfig.RoomCount;
            ushort startAddress = 100;
            
            for (int i = 1; i <= count; i++)
            {
                RoomEntity room = new(Plc, ConfigProvider)
                {
                    Id = i 
                };
                room.Name = $"房间{room.Id}";
                room.Address = startAddress;
                collection.Add(room);
                startAddress = (ushort)(startAddress + 100);//每个房间占100个寄存器

                //加载房间参数
                var param = ConfigProvider.Config.SoftwareConfig.RoomParameters.FirstOrDefault(p => p.RoomId == room.Id);
                if (param == null)
                {
                    param = new RoomParameter { RoomId = room.Id };
                    ConfigProvider.Config.SoftwareConfig.RoomParameters.Add(param);
                }
                room.RoomParameter = param;//绑定参数

                //加载房间的缓存
                var cache = CacheManager.Caches.FirstOrDefault(t => t.RoomId == room.Id);
                if (cache == null)
                {
                    cache = new CacheEntity { RoomId = room.Id };
                    CacheManager.Caches.Add(cache);
                    CacheManager.Save();
                }
                room.Cache = cache;//绑定缓存

                //使用缓存数据
                var program = ProgramManager.Programs.FirstOrDefault(p => p.Name == cache.ProgramName);//从程序列表中查找
                if (program != null)
                {
                    room.Program = program;
                    if(room.Cache.RoomMode == Enums.RoomMode.Running)
                    {
                        //接续上次运行 - 在后台运行，不阻塞初始化
                        _ = Task.Run(async () =>
                        {
                            try
                            {
                                await room.RunAsync(room.Cache.StartTime);
                            }
                            catch (Exception ex)
                            {
                                System.Diagnostics.Debug.WriteLine($"房间 {room.Id} 运行失败: {ex.Message}");
                                // 可以考虑设置房间状态为停止
                                room.RoomMode = Enums.RoomMode.Stopping;
                            }
                        });
                    }
                }
                //保存报警记录
                room.OnAlarm += (entity) =>
                {
                   System.Diagnostics.Debug.WriteLine($"房间 {entity.Id} 发生报警: {entity.RoomNumber} ");
                    lock (_lock)
                    {
                        AlarmRepository.Insert(entity);
                    }
                };
            }

            //显示房间
            foreach (var room in collection)
            {
                CurrentRoom ??= room;
                Rooms.Add(room);
            }
            
            System.Diagnostics.Debug.WriteLine("房间初始化完成");
        }
    }
}
